home *** CD-ROM | disk | FTP | other *** search
/ Risc World 3 / Risc World 3.iso / SOFTWARE / ISSUE6 / PD / PDF / pdf / c++ / FileInfo < prev    next >
Text File  |  2003-02-14  |  12KB  |  374 lines

  1. //--------------------------------------------------------------------------
  2. //
  3. //   Copyright (c) 2002, Colin Granville
  4. //
  5. //   All rights reserved.
  6. //
  7. //   Redistribution and use in source and binary forms, with or
  8. //   without modification, are permitted provided that the following 
  9. //   conditions are met:
  10. //
  11. //      * Redistributions of source code must retain the above copyright 
  12. //        notice, this list of conditions and the following disclaimer.
  13. //
  14. //      * Redistributions in binary form must reproduce the above 
  15. //        copyright notice, this list of conditions and the following 
  16. //        disclaimer in the documentation and/or other materials 
  17. //        provided with the distribution.
  18. //
  19. //      * The name Colin Granville may not be used to endorse or promote 
  20. //        products derived from this software without specific prior 
  21. //        written permission.
  22. //
  23. //   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  24. //   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  25. //   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
  26. //   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
  27. //   COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
  28. //   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
  29. //   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
  30. //   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
  31. //   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
  32. //   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
  33. //   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
  34. //   OF THE POSSIBILITY OF SUCH DAMAGE.
  35. //
  36. //--------------------------------------------------------------------------
  37.  
  38. #include "FileInfo.h"
  39. #include "GuiWindow.h"
  40. #include "PDFDoc.h"
  41. #include "GuiTargets.h"
  42. #include "Object.h"
  43. #include "dict.h"
  44. #include <time.h>
  45. #include "file.h"
  46. #include "strstream.h"
  47. #include <math.h>
  48. #include "DrawOutputFont.h"
  49. #include <iomanip.h>
  50. #include "guilib:gfx.h"
  51.  
  52. //******************************************************************************
  53.  
  54. class FileInfoFont
  55. {
  56.   public:
  57.     FileInfoFont(const char* name,int size,int height);
  58.     ~FileInfoFont();
  59.     int getHandle() {return handle;}
  60.   private:
  61.     int handle;
  62. };
  63.  
  64. //******************************************************************************
  65.  
  66. FileInfoFont::FileInfoFont(const char* name,int size,int height)
  67.   : handle(0)
  68. {
  69.   _swix(Font_FindFont,_INR(1,5)|_OUT(0),name,size,height,0,0,&handle);
  70. }
  71.  
  72. //******************************************************************************
  73.  
  74. FileInfoFont::~FileInfoFont()
  75. {
  76.   if (handle)  _swix(Font_LoseFont,_IN(0),handle);
  77. }
  78.  
  79.  
  80. //******************************************************************************
  81.  
  82. class FileInfo
  83. {
  84.   public:
  85.     FileInfo();
  86.     void setData(const FileInfoData& d);
  87.   private:
  88.     GuiWindow window;
  89.     const FileInfoData* data;
  90.     GUI_DECLARE_EVENT_TARGETS(FileInfo);
  91.  
  92.     GuiWimpTarget redrawWindowTarget;
  93.     Claim redrawWindow(GuiWimpPollBlock&,const GuiIdBlock&);
  94.  
  95.     GuiToolboxTarget hasBeenHiddenTarget;
  96.     Claim hasBeenHidden(GuiToolboxEvent&,const GuiIdBlock&);
  97. };
  98.  
  99. //******************************************************************************
  100.  
  101. FileInfo::FileInfo()
  102.   : window("FileInfo"),
  103.     redrawWindowTarget(&window,GuiWimp_ERedrawWindow,this,FileInfo::redrawWindow),
  104.     hasBeenHiddenTarget(&window,GuiWindow::HasBeenHidden::Event,this,FileInfo::hasBeenHidden)
  105. {
  106. }
  107.  
  108. //*************************************************************************
  109.  
  110. Claim FileInfo::hasBeenHidden(GuiToolboxEvent&,const GuiIdBlock&)
  111. {
  112.   GuiGetWindowStateBlock ws;
  113.   window.getState(ws);
  114.   ws.xscroll=0;
  115.   ws.yscroll=0;
  116.   ws.visibleArea.setWidth(868);
  117.   ws.visibleArea.setHeight(264);
  118.  
  119.   // Resize window.
  120.   // Can't use toolbox as it calls events.
  121.   // The window isn't actually displayed.
  122.   // Can't resize before showing because
  123.   // it opens on a menu
  124.   _swix(Wimp_OpenWindow,_IN(1),&ws);
  125.   _swix(Wimp_CloseWindow,_IN(1),&ws);
  126.   return CLAIM;
  127. }
  128.  
  129. //*************************************************************************
  130.  
  131. void getMaxWidth(FileInfoFont& font,const string& s,int& maxwid)
  132. {
  133.   int wid;
  134.   _swix(Font_ScanString,_INR(0,5) | _OUT(3),font.getHandle(),s.c_str(),(1<<8),-1,-1,0,&wid);
  135.   if (wid>maxwid) maxwid=wid;
  136. }
  137.  
  138. //*************************************************************************
  139.  
  140. void FileInfo::setData(const FileInfoData& d)
  141. {
  142.    data=&d;
  143.    FileInfoFont base("Homerton.medium",12*16,12*16);
  144.    int maxwid=320;
  145.    getMaxWidth(base,data->filename,maxwid);
  146.    getMaxWidth(base,data->title,maxwid);
  147.    getMaxWidth(base,data->subject,maxwid);
  148.    getMaxWidth(base,data->keywords,maxwid);
  149.    getMaxWidth(base,data->author,maxwid);
  150.    getMaxWidth(base,data->creator,maxwid);
  151.    getMaxWidth(base,data->producer,maxwid);
  152.    getMaxWidth(base,data->creationDate,maxwid);
  153.    getMaxWidth(base,data->modDate,maxwid);
  154.    getMaxWidth(base,data->pages,maxwid);
  155.    getMaxWidth(base,data->pageSize,maxwid);
  156.    getMaxWidth(base,data->fileSize,maxwid);
  157.    getMaxWidth(base,data->tagged,maxwid);
  158.    getMaxWidth(base,data->permissions,maxwid);
  159.    getMaxWidth(base,data->optimised,maxwid);
  160.    getMaxWidth(base,data->pdfVersion,maxwid);
  161.    maxwid/=400;
  162.  
  163.    GuiBBox box;
  164.    window.getExtent(box);
  165.    box.setWidth(8+224+maxwid+20);
  166.    window.setExtent(box);
  167.  
  168.    
  169. }
  170.  
  171. //*************************************************************************
  172.  
  173. #define FI_HEIGHT 40
  174. bool showLine(int x,int &y,FileInfoFont& bold,const char* name,
  175.                    FileInfoFont& base,const string& value,
  176.                    GuiRedrawWindowBlock& block)
  177. {
  178.   y-=FI_HEIGHT;
  179.   if (y+FI_HEIGHT <= block.redrawArea.ymin) return 0;
  180.   if (y < block.redrawArea.ymax)
  181.   {
  182.     int wid;
  183.     _swix(Font_ScanString,_INR(0,5) | _OUT(3),bold.getHandle(),name,(1<<8),-1,-1,0,&wid);
  184.     int offset=200*400-wid;
  185.     _swix(ColourTrans_SetFontColours,_INR(0,3),bold.getHandle(),0xdddddd00,0,14);
  186.     _swix(Font_Paint,_INR(0,7),bold.getHandle(),name,(1<<8),x*400+offset,y*400+FI_HEIGHT*400*5/16,0,0,0);
  187.     _swix(ColourTrans_SetFontColours,_INR(0,3),base.getHandle(),0xdddddd00,0,14);
  188.     _swix(Font_Paint,_INR(0,7),base.getHandle(),(value.size()?value.c_str():"--"),(1<<8),
  189.                                                 (x+224+8)*400,y*400+FI_HEIGHT*400*5/16,0,0,0);
  190.   }
  191.   return 1;
  192. }
  193. //*************************************************************************
  194.  
  195. Claim FileInfo::redrawWindow(GuiWimpPollBlock& wpb,const GuiIdBlock&)
  196. {
  197.   bool more;
  198.   GuiRedrawWindowBlock& block=wpb.redrawWindowRequest;
  199.   FileInfoFont base("Homerton.medium",12*16,12*16);
  200.   FileInfoFont bold("Homerton.bold",12*16,12*16);
  201.  
  202.   for (GuiWindow::redraw(block,more);more;GuiWindow::getRectangle(block,more))
  203.   {
  204.    if (data)
  205.    {
  206.       int x=block.xToScreen(8);
  207.       int y=block.yToScreen(-8);
  208.       gfx::gcol_bgr(0,0xdddddd00);
  209.       gfx::rectanglefill(block.xToScreen(224),block.yToScreen(-1280),1280,1280);
  210.       gfx::gcol_bgr(0,0x99999900);
  211.       gfx::rectanglefill(block.xToScreen(224-4),block.yToScreen(-1280),2,1280);
  212.       gfx::gcol_bgr(0,0xffffff00);
  213.       gfx::rectanglefill(block.xToScreen(224),block.yToScreen(-1280),2,1280);
  214.  
  215.       if (!showLine(x,y,bold,"Title",base,data->title,block)) break;
  216.       if (!showLine(x,y,bold,"Subject",base,data->subject,block)) break;
  217.       if (!showLine(x,y,bold,"Keywords",base,data->keywords,block)) break;
  218.       y-=12;
  219.       if (!showLine(x,y,bold,"Author",base,data->author,block)) break;
  220.       if (!showLine(x,y,bold,"Creator",base,data->creator,block)) break;
  221.       if (!showLine(x,y,bold,"Producer",base,data->producer,block)) break;
  222.       y-=12;
  223.       if (!showLine(x,y,bold,"Creation Date",base,data->creationDate,block)) break;
  224.       if (!showLine(x,y,bold,"Mod Date",base,data->modDate,block)) break;
  225.       y-=12;
  226.       if (!showLine(x,y,bold,"Pages",base,data->pages,block)) break;
  227.       if (!showLine(x,y,bold,"Page size",base,data->pageSize,block)) break;
  228.       y-=12;
  229.       if (!showLine(x,y,bold,"File name",base,data->filename,block)) break;
  230.       if (!showLine(x,y,bold,"File size",base,data->fileSize,block)) break;
  231.       if (!showLine(x,y,bold,"Access",base,data->permissions,block)) break;
  232.       y-=12;
  233.       if (!showLine(x,y,bold,"Tagged",base,data->tagged,block)) break;
  234.       if (!showLine(x,y,bold,"Optimised",base,data->optimised,block)) break;
  235.       if (!showLine(x,y,bold,"PDF Version",base,data->pdfVersion,block)) break;
  236.     }
  237.   }
  238.  
  239.   return CLAIM;
  240. }
  241.  
  242. //*************************************************************************
  243.  
  244. string getInfo(PDFDoc& doc,const char* key)
  245. {
  246.   string res;
  247.   Object info;
  248.   Object obj;
  249.   doc.getDocInfo(&info);
  250.   if (info.isDict()) info.dictLookup((char*)key, &obj);
  251.  
  252.   if (obj.isString()) 
  253.      res=toAcornLatin1(obj.getString()->getCString(),
  254.                        obj.getString()->getLength());
  255.   obj.free();
  256.   info.free();
  257.   return res;
  258. }
  259. //*************************************************************************
  260.  
  261. string getInfoDate(PDFDoc& doc, const char* key)
  262. {
  263.   string res;
  264.   Object info;
  265.   Object obj;
  266.   doc.getDocInfo(&info);
  267.   if (info.isDict()) info.dictLookup((char*)key, &obj);
  268.  
  269.   if (obj.isString())
  270.   {
  271.     char* s=obj.getString()->getCString();
  272.     if (s[0] == 'D' && s[1] == ':') s += 2;
  273.  
  274.     struct tm tmStruct;
  275.     if (sscanf(s, "%4d%2d%2d%2d%2d%2d", &tmStruct.tm_year,
  276.                                         &tmStruct.tm_mon,
  277.                                         &tmStruct.tm_mday,
  278.                                         &tmStruct.tm_hour,
  279.                                         &tmStruct.tm_min,
  280.                                         &tmStruct.tm_sec)==6)
  281.     {
  282.       tmStruct.tm_year-= 1900;
  283.       tmStruct.tm_mon-= 1;
  284.       tmStruct.tm_wday = -1;
  285.       tmStruct.tm_yday = -1;
  286.       tmStruct.tm_isdst = -1;
  287.       mktime(&tmStruct); // compute the tm_wday and tm_yday fields
  288.  
  289.       char buf[256];
  290.       if (strftime(buf, sizeof(buf), "%c", &tmStruct)) 
  291.         res=buf;
  292.       else
  293.         res=s;
  294.     }
  295.     else res=s;
  296.   }
  297.   obj.free();
  298.   info.free();
  299.   return res;
  300. }
  301. //*************************************************************************
  302.  
  303. void FileInfo_create(FileInfoData& data ,PDFDoc& doc,const string& filename)
  304. {
  305.   data.filename=filename;
  306.   data.title=getInfo(doc,"Title");
  307.   data.subject=getInfo(doc,"Subject");
  308.   data.keywords=getInfo(doc,"Keywords");
  309.   data.author=getInfo(doc,"Author");
  310.   data.creator=getInfo(doc,"Creator");
  311.   data.producer=getInfo(doc,"Producer");
  312.   data.creationDate=getInfoDate(doc,"CreationDate");
  313.   data.modDate=getInfoDate(doc,"ModDate");
  314.  
  315.   data.tagged=(doc.getStructTreeRoot()->isDict() ? "yes" : "no");
  316.  
  317.   char buf[256];
  318.   ostrstream out(buf,256);
  319.   out << doc.getNumPages();
  320.   data.pages=out.str();
  321.  
  322.   out.seekp(0);
  323.  
  324.   out << "Print:" << (doc.okToPrint(gTrue) ? "yes  " : "no  ");
  325.   out << "Copy:" << (doc.okToCopy(gTrue) ? "yes  " : "no  ");
  326.   out << "Modify:" << (doc.okToChange(gTrue) ? "yes  " : "no  ");
  327.   out << "Add notes:" << (doc.okToAddNotes(gTrue) ? "yes" : "no");
  328.   data.permissions=out.str();
  329.  
  330.   // get page size
  331.   if (doc.getNumPages() >= 1) 
  332.   {
  333.     out.seekp(0);
  334.     double w,h;
  335.     w = doc.getPageWidth(1);
  336.     h = doc.getPageHeight(1);
  337.     out.setf(ios::fixed);
  338.     out << setprecision(1) << w*25.4/72<< " x " << h*25.4/72 << " mm";
  339.     if ((fabs(w - 612) < 0.1 && fabs(h - 792) < 0.1) ||
  340.         (fabs(w - 792) < 0.1 && fabs(h - 612) < 0.1)) 
  341.     {
  342.       out << " (letter)";
  343.     } 
  344.     else if ((fabs(w - 595) < 0.1 && fabs(h - 842) < 0.1) ||
  345.                (fabs(w - 842) < 0.1 && fabs(h - 595) < 0.1)) 
  346.     {
  347.       out << " (A4)";
  348.     }
  349.     data.pageSize=out.str();
  350.   } 
  351.  
  352.   out.seekp(0);
  353.   int len;
  354.   if (isFile(filename.c_str(),0,&len))
  355.   {
  356.      out << len << " bytes";
  357.      data.fileSize=out.str();
  358.   }
  359.  
  360.   data.optimised=(doc.isLinearized() ? "yes" : "no");
  361.  
  362.   out.seekp(0);
  363.   out << doc.getPDFVersion();
  364.   data.pdfVersion=out.str();
  365. }
  366. //******************************************************************************
  367.  
  368. void FileInfo_ATBS(const FileInfoData& data)
  369. {
  370.   static FileInfo info;
  371.   info.setData(data);
  372. }
  373.  
  374.